﻿#include "pch.h"
#include "Block2.h"
#include "Game.h"

/**
 * 构造方法。
 */
Block2::Block2() {
    for (int j = 0; j < Const::BLOCK_GRID_COUNT_V; j++) {
        mBlocks[1][j].mUsed = TRUE;
    }
}

/**
 * 进入预览区域。
 * @param drawer    绘图者
 */
void Block2::EnterPreview(CDC* drawer) {
    int x = Const::PREVIEW_WIDTH / 2 - Const::GRID_SIZE * 2;
    int y = (Const::PREVIEW_HEIGHT - Const::GRID_SIZE) / 2;

    for (int j = 0; j < Const::BLOCK_GRID_COUNT_H; j++) {
        CRect rect(x + Const::GRID_SIZE * j, y, x + Const::GRID_SIZE * (j + 1), y + Const::GRID_SIZE);
        drawer->FillSolidRect(rect, mColor);
        drawer->DrawEdge(rect, EDGE_RAISED, BF_RECT);
    }
}

/**
 * 擦除。
 */
void Block2::Erase() {
    RECT rect = { 0 };

    switch (mShape) {
        case ONE:
            rect.left = Const::GRID_SIZE * mLine;
            rect.top = Const::GRID_SIZE * (mRow + 1);
            rect.right = rect.left + Const::GRID_SIZE * 4;
            rect.bottom = rect.top + Const::GRID_SIZE;
            break;
        case TWO:
            rect.left = Const::GRID_SIZE * (mLine + 1);
            rect.top = Const::GRID_SIZE * mRow;
            rect.right = rect.left + Const::GRID_SIZE;
            rect.bottom = rect.top + Const::GRID_SIZE * 4;
            break;
    }
    Block::EraseRect(&rect);
}

/**
 * 获取底端所在的行数。底端是指方块最下方的有效格。
 * @return 底端所在的行数
 */
int Block2::GetBottom() {
    if (mShape == ONE) {
        return mRow + 1;
    }
    return mRow + 3;
}

/**
 * 获取顶端所在的行数。顶端是指方块最上方的有效格。
 * @return 顶端所在的行数
 */
int Block2::GetTop() {
    if (mShape == ONE) {
        return mRow + 1;
    }
    return mRow;
}

/**
 * 对不能下落的处理。
 */
void Block2::HandleCannotMoveDown() {
    int i, j;
    switch (mShape) {
        case ONE:
            for (j = 0; j < Const::BLOCK_GRID_COUNT_H; j++) {
                Game::sExistentBlocks[mRow + 1][mLine + j].mUsed = TRUE;
                Game::sExistentBlocks[mRow + 1][mLine + j].mColor = mColor;
            }
            break;
        case TWO:
            for (i = 0; i < Const::BLOCK_GRID_COUNT_V; i++) {
                Game::sExistentBlocks[mRow + i][mLine + 1].mUsed = TRUE;
                Game::sExistentBlocks[mRow + i][mLine + 1].mColor = mColor;
            }
            break;
    }
}

/**
 * 下落。
 * @return 成功则返回 TRUE，否则返回 FALSE
 */
BOOL Block2::MoveDown() {
    switch (mShape) {
        case ONE:
            if (mRow == 18) {
                this->HandleCannotMoveDown();
                return FALSE;
            }
            for (int i = 0; i < Const::BLOCK_GRID_COUNT_H; i++) {
                if (Game::sExistentBlocks[mRow + 2][mLine + i].mUsed) {
                    this->HandleCannotMoveDown();
                    return FALSE;
                }
            }
            break;
        case TWO:
            if (mRow == 16) {
                this->HandleCannotMoveDown();
                return FALSE;
            }
            if (Game::sExistentBlocks[mRow + 4][mLine + 1].mUsed) {
                this->HandleCannotMoveDown();
                return FALSE;
            }
            break;
    }

    return Block::MoveDown();
}

/**
 * 左移。
 */
void Block2::MoveLeft() {
    switch (mShape) {
        case ONE:
            if (mLine == 0) {
                return;
            }
            if (Game::sExistentBlocks[mRow + 1][mLine - 1].mUsed) {
                return;
            }
            break;
        case TWO:
            if (mLine == -1) {
                return;
            }
            for (int i = 0; i < Const::BLOCK_GRID_COUNT_V; i++) {
                if (Game::sExistentBlocks[mRow + i][mLine].mUsed) {
                    return;
                }
            }
            break;
    }

    Block::MoveLeft();
}

/**
 * 右移。
 */
void Block2::MoveRight() {
    switch (mShape) {
        case ONE:
            if (mLine == 6) {
                return;
            }
            if (Game::sExistentBlocks[mRow + 1][mLine + 4].mUsed) {
                return;
            }
            break;
        case TWO:
            if (mLine == 8) {
                return;
            }
            for (int i = 0; i < Const::BLOCK_GRID_COUNT_V; i++) {
                if (Game::sExistentBlocks[mRow + i][mLine + 2].mUsed) {
                    return;
                }
            }
            break;
    }

    Block::MoveRight();
}

/**
 * 变形。
 */
void Block2::Transform() {
    switch (mShape) {
        case ONE:
            if (mRow == -1 || mRow >= 17) {
                return;
            }
            if (Game::sExistentBlocks[mRow][mLine + 1].mUsed || 
                Game::sExistentBlocks[mRow + 2][mLine + 1].mUsed || 
                Game::sExistentBlocks[mRow + 3][mLine + 1].mUsed) {
                return;
            }
            this->Erase();
            mBlocks[1][0].mUsed = mBlocks[1][2].mUsed = mBlocks[1][3].mUsed = FALSE;
            mBlocks[0][1].mUsed = mBlocks[2][1].mUsed = mBlocks[3][1].mUsed = TRUE;
            mShape = TWO;
            break;
        case TWO:
            if (mLine == -1 || mLine >= 7) {
                return;
            }
            if (Game::sExistentBlocks[mRow + 1][mLine].mUsed || 
                Game::sExistentBlocks[mRow + 1][mLine + 2].mUsed || 
                Game::sExistentBlocks[mRow + 1][mLine + 3].mUsed) {
                return;
            }
            this->Erase();
            mBlocks[1][0].mUsed = mBlocks[1][2].mUsed = mBlocks[1][3].mUsed = TRUE;
            mBlocks[0][1].mUsed = mBlocks[2][1].mUsed = mBlocks[3][1].mUsed = FALSE;
            mShape = ONE;
            break;
    }

    Block::Draw();
}
